package com.henrich.ccb.java8stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * <p>功能描述：归约 </p>
 * 把一个流缩减成一个值，能实现对集合求和、求乘积和求最值操作。
 * <p>修订记录</p>
 *
 * @Author xianghui.zh
 * @Version 1.0 2022/2/21
 **/
public class ReduceDemo {
    public static void main(String[] args) {
        // 案例一：求Integer集合的元素之和、乘积和最大值。
        List<Integer> list = Arrays.asList(1, 3, 2, 8, 11, 4);
        // 求和方式1
        Optional<Integer> sum1 = list.stream().reduce((x, y) -> x + y);
        // 求和方式2
        Optional<Integer> sum2 = list.stream().reduce(Integer::sum);
        // 求和方式3
        Integer sum3 = list.stream().reduce(0, Integer::sum);
        System.out.println("sum1: " + sum1.get() + "\nsum2: " + sum2.get() + "\nsum3: " + sum3);
        // 求乘积
        Optional<Integer> multi = list.stream().reduce((x, y) -> x * y);
        System.out.println("乘积：" + multi.get());
        // 求最大值1
        Integer max = list.stream().reduce(1, Integer::max);
        // 求最大值2
        Optional<Integer> max2 = list.stream().reduce((x, y) -> x > y ? x : y);
        System.out.println("max: " + max + "\nmax2: " + max2.get());

        // 案例二：求所有员工的工资之和和最高工资。
        List<Person> personList = new ArrayList<Person>();
        personList.add(new Person("Tom", 8900, 23, "male", "New York"));
        personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
        personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
        personList.add(new Person("Anni", 8200, 24, "female", "New York"));
        personList.add(new Person("Owen", 9500, 25, "male", "New York"));
        personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
        Integer sumSalary1 = personList.stream().map(Person::getSalary).reduce(0, Integer::sum);
        Integer sumSalary2 = personList.stream().reduce(0, (m, p) -> m += p.getSalary(), (m1, m2) -> m1 + m2);
        Integer maxSalary = personList.stream().map(Person::getSalary).reduce(1, Integer::max);
        System.out.println("sumSalary1:" + sumSalary1);
        System.out.println("sumSalary2:" + sumSalary2);
        System.out.println("maxSalary:" + maxSalary);

    }
}
